<style lang="scss" scoped>
.agreement {
  width: 750rpx;
  left: 0;
  position: fixed;
  bottom: 25px;
}

page{
  background: #f8f8f8;
}
.page-wrap {
	background: #f8f8f8;
}

.sub-btn {
  background: $fun-primary-color;
  color: #fff;
  border-color: $fun-primary-color;
}

button {
  line-height: 2.3;
}

.form {
  .form-item {
    margin: 0 50rpx 30rpx;
    border-bottom: 1px solid #e7e7e7;
    height: 80rpx;
    display: flex;
    align-items: center;

    .sendCaptcha {

      .text {
        color: #999;
        opacity: 1;

        &.active {
          color: $fun-primary-color;
        }
      }
    }

    .fun-input {
      flex: 1;
      height: 80rpx;
      line-height: 80rpx;
      font-size: 14px;
      color: #444;
      text-align: left;

    }

  }

  .action {
    margin: 50rpx 50rpx 30rpx;
    display: block;
  }

}

.placeholder {
  color: #fff;
}

.joinForm {
  width: 500rpx;
  text-align: center;

  .input {
    border: 1px solid #e7e7e7;
    line-height: 36px;
    height: 36px;
    font-size: 14px;
    text-align: left;
    padding: 0 10px;
  }

  .numbox {
    display: flex;
    justify-content: center; //x轴排列
  }
}

.pwd-wrap {
  width: 750rpx;
  bottom: 0;
  padding-top: 25px;
  box-sizing: border-box;
  position: fixed;
  background: white;
  z-index: 10;
}

.wrap {
  text-align: center;
  height: 100vh;
  color: #333;
  box-sizing: border-box;
  background: #fff;
}

.img {
  width: 200rpx;
  height: 200rpx;
  margin: 0 auto 100rpx;
  display: block;
}

.imgWx {
  width: 100px;
  height: 100px;
  margin: 180rpx 0 180rpx;
}

.otherLogin-top-item {
  width: 630rpx;
  height: 88rpx;
  border-radius: 4px;
  margin: 0 auto;
  text-align: center;
  line-height: 88rpx;
  color: white;
}

.snslogin {
  position: absolute;
  bottom: 60rpx;
  width: 750rpx;

  .tip {
    position: relative;
    margin: 0 auto;
    width: 60px;
    text-align: center;

    .after, .before {
      position: absolute;
      height: 1px;
      background: #ccc;
      width: 40px;
      top: 50%;
    }

    .after {
      left: 0;
      transform: translateX(-100%);
    }

    .before {
      right: 0;
      transform: translateX(100%);
    }

  }

  .list {
    margin: 15px auto;
    width: 300px;
    text-align: center;
  }
}

.channel {
  &-list {
    position: absolute;
    bottom: 60px;
    width: 750rpx;
    display: flex;
    justify-content: center;
    align-items: center;

  }

  &-item {
    background: none;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 6px;

    .btn {
      width: 100%;
      height: 100%;
      background: none;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .btn::after {
      width: 0px !important;
      height: 0px !important;
      display: none;
      content: ''
    }

    .icon {

    }

    .text {
      padding-left: 6px;
    }
  }

}

.wxBtn {
  background: #59a228 !important;
  color: #FFFFFF;
}

.phoneIcon {
  position: fixed;
  bottom: 50px;
  left: 0;
  width: 100%;
  padding: 0px;
}
</style>
<template>
  <div class="page-wrap">
    <fun-err-msg :errs="formCheckResult" ref="refMsg"></fun-err-msg>
    <div class="h25"></div>
    <image src="/static/logo.png" class="img"></image>
    <div class="form">
      <form @reset="formReset" @submit="formSubmit" style="display: block">
        <div class="form-item uni-column">
          <input @input="inputPhone" type="number" class="fun-input" name="input" placeholder="请输入手机号码"/>
        </div>
        <div class="form-item uni-column" v-if="mode==='code'">
          <input @input="inputCaptcha" type="number" class="fun-input" name="captcha" placeholder="请输入短信验证码"/>
          <div class="sendCaptcha">
            <span @click="sendCaptcha" class="text" v-if="!captchaSend">获取验证码</span><span class="text active" v-else>{{s}}s</span>
          </div>
        </div>
        <div class="form-item uni-column" v-if="mode==='password'">
          <input @input="inputPassword" class="fun-input" name="password" placeholder="请输入密码" type="password"/>
        </div>
        <div class="action">
          <div>
            <button class="sub-btn m-b-15" form-type="submit">立即登录</button>
          </div>
          <div>
            <button @click="cancel" class="sub-btn-cancel m-b-20" >暂不登录</button>
          </div>

          <div class="flex flex-vertical-center flex-justify-between c7 fz-12 p-t-10">
            <span @click="toForget" class="text">忘记密码</span>
            <span @click="toRegister" class="text">注册账号</span>
          </div>
        </div>
      </form>
    </div>

    <div class="channel-list p-b-safe-area">
      <div class="channel-item" v-if="showWxLogin">
        <!-- #ifdef MP-WEIXIN -->
        <button v-if="canIUseGetUserProfile" @click="getUserProfile" class="btn">
          <layout-icon class="icon" color="#09bb07" size="24" type="icon-weixin"></layout-icon>
          <span class="text fz-14">微信登录</span>
        </button>
        <button v-else @getuserinfo="weixinlogin" class="btn" open-type="getUserInfo">
          <layout-icon class="icon" color="#09bb07" size="24" type="icon-weixin"></layout-icon>
          <span class="text fz-14">微信登录</span>
        </button>
        <!-- #endif -->
        <!-- #ifdef APP-PLUS -->
        <button @click="weixinlogin" class="btn">
          <layout-icon class="icon" color="#09bb07" size="24" type="icon-weixin"></layout-icon>
          <span class="text fz-14">微信登录</span>
        </button>
        <!-- #endif -->

      </div>
      <div @click="setMode('code')" class="channel-item" open-type="getUserInfo" v-if="mode==='password'">
        <layout-icon class="icon" color="#999" size="24" type="icon-shouji"></layout-icon>
        <span class="text fz-14">验证码登录</span>
      </div>
      <div @click="setMode('password')" class="channel-item" open-type="getUserInfo" v-if="mode==='code'">
        <layout-icon class="icon" color="#999" size="24" type="icon-mimadenglu"></layout-icon>
        <span class="text fz-14">密码登录</span>
      </div>
    </div>

    <div class="agreement p-b-safe-area flex flex-vertical-center flex-justify-c">
      <div class="fz-12 text-right c9">登录即表示您已阅读并接受<span class="c3 text-underline">《用户服务协议》</span></div>
    </div>
    <layout-popup :autoClose="false" :showMask="false" ref="phone">
      <div class="form pwd-wrap">
        <div class="form-item uni-column">
          <input @input="inputPhone" class="fun-input" name="input" placeholder="请输入手机号码"/>
        </div>
        <div class="form-item uni-column">
          <input @input="inputCaptcha" class="fun-input" name="captcha" placeholder="请输入短信验证码"/>
          <div class="sendCaptcha">
            <span @click="sendCaptcha" class="text" v-if="!captchaSend">获取验证码</span><span class="text active" v-else>{{s}}s</span>
          </div>
        </div>
        <div class="action">
          <div>
            <button @click="bingPhoneFn" class="sub-btn m-b-15">立即绑定</button>
          </div>
        </div>
      </div>
    </layout-popup>

  </div>
</template>

<script>

import { error } from '@/common/fun'
import { getAuthUrl, login, sendSms, snsLogin, userUniLogin } from '@/api/user'
import { regPhone } from '@/common/Regs'
import { urlencode, validateFun, GetQueryByString } from '@/common/helper'
import Promisify from '@/common/Promisify'
import Storage from '@/common/Storage'
import { pageMixin } from '@/mixins'
import FunErrMsg from '@/components/fun-err-msg/fun-err-msg'
import LayoutPopup from '@/components/layout-popup/layout-popup'
import LayoutIcon from '@/components/layout-icon/layout-icon'
import { Exception } from '@/common/Exception'
import ENV from '@/common/env'
import { getEnv } from '@/common/request'
import { mapActions } from 'vuex'

export default {
  name: 'Login',
  mixins: [pageMixin],
  computed: {
    ischeck () {
      return this.$store.getters['system/getIsCHeck']
    }
  },
  components: {
    LayoutIcon,
    LayoutPopup,
    FunErrMsg
  },
  data () {
    return {
      canIUseGetUserProfile: false,
      env: '',
      smisid: '',
      showWxLogin: false,
      logourl: ENV.logoplain,
      wx_code: '',
      h5_wx_login: false,
      mode: 'code',
      binbPhoneShow: false,
      bindPwdShow: false,
      pageTitle: '登录',
      setintervalInstance: null,
      phone: '',
      captcha: '',
      password: '',
      s: 120,
      formCheckResult: false,
      smsid: null,
      pwd: '',
      pwdConfirm: '',
      captchaSend: false,
      bindPhoneTempData: null// 如果需要绑定手机，需要临时储存服务端给的信息
    }
  },
  methods: {
    toForget () {
      this.$linkTo('/pages/user/forget')
    },
    toRegister () {
      this.$linkTo('/pages/user/register')
    },
    cancel () {
      this.$back()
    },
    formReset () {

    },
    minusFn () {
      if (this.s > 1) {
        this.s--
        return
      }
      clearInterval(this.setintervalInstance)
      this.captchaSend = false
    },
    sendCaptcha () {
      if (!this.phone) {
        error('发送验证码失败')
        return
      }

      sendSms({
        phone: this.phone,
        type: 'login'
      }, { tip: '发送验证码' }).then(res => {
        this.smsid = res.data
        this.captchaSend = true
        this.s = 120
        this.setintervalInstance = setInterval(this.minusFn.bind(this), 1000)
      }).catch(() => {
      })
    },
    inputPassword (e) {
      this.password = e.detail.value
    },
    inputCaptcha (e) {
      this.captcha = e.detail.value
    },
    inputPhone (e) {
      this.phone = e.detail.value
    },
    /**
     * 绑定手机
     * @returns {Promise<void>}
     */
    async bingPhoneFn () {
      try {
        const wxLoginRt = await Promisify('login').catch(() => {
          throw Error('微信login错误')
        })
        const { code: lp_code } = wxLoginRt

        // 获取暂存的userInfO和code
        const lp_raw_data = JSON.stringify(this.bindPhoneTempData)

        const postData = {
          login_method: 'wx_lp',
          code: lp_code,
          lp_raw_data,
          mobile: this.phone,
          captcha: this.captcha
        }
        const rule = {
          login_method: {
            required: true,
            type: String,
            message: {
              required: '登录方式必填'
            }
          },
          account: {
            type: String,
            match: regPhone,
            required: true,
            length: 11,
            message: {
              length: '手机号码必须为11位',
              required: '登录方式必填',
              match: '手机号格式不符'
            }
          },
          code: {
            type: String,
            required: true,
            length: 4,
            message: {
              length: '验证码为4位数字',
              required: '数字必填'
            }
          }
        }
        const checkRt = validateFun(postData, rule)
        if (checkRt !== true) {
          this.formCheckResult = checkRt
          this.$refs.refMsg.show()
          return
        }

        const { errorCode, data } = await snsLogin(postData).catch(() => {
          throw Error('第三方登录请求错误')
        })
        if (errorCode !== 0) throw Error('绑定手机号失败')
        this.loginCall(data)
      } catch (e) {
        error(e.message)
      }
    },
    async formSubmit () {
      const mode = this.mode
      const postData = { phone: this.phone }
      if (mode === 'password') {
        postData.passwd = this.password
        postData.login_method = 'phone_pwd'
      }
      if (mode === 'code') {
        postData.captcha = this.captcha
        postData.login_method = 'sms_login'
        postData.BizId = this.smsid
      }
      const rule = {
        login_method: {
          required: true,
          type: String,
          enum: ['phone_pwd', 'sms_login', 'wx_lp'],
          message: {
            required: '登录方式必选',
            enum: '登录方式仅允许是phone_pwd、sms_login、wx_lp中的一个'
          }
        },
        phone: {
          type: String,
          match: regPhone,
          required: true,
          length: 11,
          message: {
            required: '手机号必填',
            length: '手机号为长11位的字符',
            match: '手机号格式不符'
          }
        },
        captcha: mode === 'password' ? { required: false } : {
          type: String,
          required: true,
          length: 4,
          message: {
            required: '验证码必填',
            length: '验证码长度为4'
          }
        },
        passwd: mode === 'code' ? { required: false } : {
          type: String,
          required: true,
          message: {
            required: '密码必填'
          }
        }
      }

      try {
        const checkRt = validateFun(postData, rule)
        if (checkRt !== true) {
          this.formCheckResult = checkRt
          this.$refs.refMsg.show()
          throw Error('请正确填写资料')
        }

        const userData = await userUniLogin(postData, {
          reqHeader: true,
          onlyData: true
        }).catch((e) => {
          throw Error(e.msg || '登录失败')
        })

        this.loginCall(userData)
      } catch (e) {
        Exception.handle(e)
      }
    },
    async loginCall (userData) {
      const userInfo = userData.userInfo
      Storage.set('access_token', userData.access_token)
      this.$store.commit('user/SET_USER_INFO', userInfo)
      uni.$emit('login_call')
      // #ifdef H5
      if (Storage.get('login_back_url')) {
        location.replace(Storage.get('login_back_url'))
        return
      }
      // #endif

      setTimeout(() => {
        this.$back()
      }, 200)
    },
    setMode (mode) {
      this.mode = mode
      if (mode === 'password') this.pageTitle = '密码登录'
      if (mode === 'code') this.pageTitle = '验证码登录'
    },
        getUserProfile () {
      this.weixinlogin({ getUserInfoType: 'getUserProfile' })
    },
    async weixinlogin ({ getUserInfoType = 'getUserInfo' } = {}) {
      var loginReqdata
      try {
        const env = getEnv()

        if (env === 'wx_lp') {

          var wxUserInfo = {}
          if (getUserInfoType === 'getUserInfo') {
            // const checkSeting = await Promisify('getSetting').catch(() => {
            //   throw Error('获取配置失败')
            // })
            // // 未获得用户信息权限,需要让用户授权
            // if (!checkSeting.authSetting['scope.userInfo']) {
            //   await Promisify('authorize', { scope: 'scope.userInfo' }).catch(() => {
            //     throw Error('请授权登录')
            //   })
            // }
            wxUserInfo = await Promisify('getUserInfo', { lang: 'zh_CN' }).catch(() => {
              throw Error('获取用户信息失败')
            })
          } else {
            wxUserInfo = await Promisify('getUserProfile', { desc: '用于完善会员资料' }).catch((err) => {
              console.log(err)
              throw Error('获取用户信息失败')
            })
          }


          // 获取code
          const wxLoginRt = await Promisify('login').catch(() => {
            throw Error('微信login错误')
          })
          const { code: lp_code } = wxLoginRt

          // const checkSeting = await Promisify('getSetting').catch(() => {
          //   throw Error('获取配置失败')
          // })
          // // 未获得用户信息权限,需要让用户授权
          // if (!checkSeting.authSetting['scope.userInfo']) {
          //   await Promisify('authorize', { scope: 'scope.userInfo' }).catch(() => {
          //     throw Error('请授权登录')
          //   })
          // }
          // const wxUserInfo = await Promisify('getUserInfo', { lang: 'zh_CN' }).catch(() => {
          //   throw Error('获取用户信息失败')
          // })
          const { encryptedData, rawData={}, signature, userInfo, iv } = wxUserInfo
          // if (!rawData) throw Error('请允许授权')
          const lp_raw_data = JSON.stringify({
            encryptedData,
            signature,
            userInfo,
            rawData: rawData,
            iv
          })
          loginReqdata = await userUniLogin({
            login_method: env,
            code: lp_code,
            lp_raw_data
          }, { tip: '登录中' }).then(res => res.data).catch((err) => {
            throw Error(err.msg || '第三方登录请求错误')
          })
        }

        if (env === 'app') {
          const loginRes = await Promisify('login', { provider: 'weixin' })

          loginReqdata = await userUniLogin({ login_method: 'wx_app', ...loginRes.authResult }).then(res => res.data).catch(e => {
          })
          console.log(loginReqdata)
        }

        if (env === 'wx_mp') {
          // 如果url有code去掉
          let {
            origin,
            pathname,
            search,
            hash
          } = window.location
          const strArr = []
          // 如果已经有code了,那么就只要一个order_no
          if (search.indexOf('code') !== -1) {
            const tempArr = search.split('&')
            for (var i of tempArr) {
              // 过滤多余的参数
              console.log(i, i.indexOf('code') === -1, i.indexOf('state') === -1, i.indexOf('appid') === -1)
              // 过滤多余的参数
              if (i.indexOf('code') === -1 && i.indexOf('state') === -1 && i.indexOf('appid') === -1) {
                strArr.push(i)
              }
            }
            console.log(strArr)
            let newSearchStr = strArr.join('&')
            if (newSearchStr.indexOf('?') === -1) {
              newSearchStr = '?' + newSearchStr
            }

            search = newSearchStr
          }
          const REDIRECT_URI = origin + pathname + search + hash

          const wxAuthUrl = await getAuthUrl({ REDIRECT_URI }).then(res => res.data).catch((err) => {
            throw Error(err.msg)
          })
          console.log('wxAuthUrl result is ', wxAuthUrl)
          location.replace(wxAuthUrl)
          return
        }

        this.loginCall(loginReqdata)

        // 需要绑定手机号
        // if (errorCode === 88001) {
        //   this.bindPhoneTempData = data
        //   this.pageTitle = '绑定手机'
        //   this.binbPhoneShow = true // 设置这个之后，无法后退
        //   this.$refs.phone.show()
        // }
      } catch (e) {
        console.log(e)
        error(e.message)
      }
    },
    async _init_func () {
      const env = getEnv()

      if (['wx_lp', 'app', 'wx_mp'].includes(env)) {
        if (env === 'app' && this.ischeck) {
          this.showWxLogin = false
        } else {
          this.showWxLogin = true
        }
      }

      if (env === 'wx_mp') {
        const access_token = Storage.get('access_token')
        const code = GetQueryByString(location.href, 'code')
        if (code && !access_token) {
          // 如果code相同，则代表code重复
          if (code === Storage.get('wxlogin_temp_code')) {
            error('code重复使用')
            return
          }

          Storage.set('wxlogin_temp_code', code)

          this.setUserInfo({})
          const loginResData = await userUniLogin({
            login_method: env,
            code: code
          }).then(res => res.data).catch(err => {
            throw Error(err.msg)
          })

          this.h5_wx_login = true// 标记是h5微信登录
          this.loginCall(loginResData)
        }
      }
    },
    ...mapActions({
      setUserInfo: 'user/setUserInfo'
    })
  },
  onLoad () {
    // #ifdef MP-WEIXIN
    if (wx.getUserProfile) {
      this.canIUseGetUserProfile = true
    }
    // #endif
    this._init_func()
  }
}
</script>

